#include "stdafx.h"
#include "Comm.h"


Comm::Comm(void)
{
	_hCom = NULL;
	_iBufferSize = 1024*8;
}


Comm::~Comm(void)
{
	close();
}

int Comm::open(int iPort, int iBaud, int iBit, int iParity, int iStopBit)
{
	CString strCom;
	int iRc = 0;

	if(iPort<1 || iBaud<BAUD_075 || iBit<DATABITS_5 || iStopBit<STOPBITS_10)
	{
		return COMM_BAD_PARAMS;
	}

	if(_hCom != NULL)
	{
		return COMM_ALREADY_OPEN;
	}

	strCom.Format(L"COM%d", iPort);

	_hCom=::CreateFile(strCom, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING , 0, 0);
	if (_hCom!=0 || _hCom!=INVALID_HANDLE_VALUE)
	{
		if( ( iRc = setTimeOut(100)  ) != COMM_NO_ERROR)
		{
			close();
			return iRc;
		}

		if ( !::SetupComm(_hCom, _iBufferSize, _iBufferSize) ) 
		{
			close();
			return COMM_BAD_PARAMS;
		}

		if ( (iRc = changeParameters(iBaud, iBit, iParity, iStopBit)) !=  COMM_NO_ERROR)
		{
			close();
			return iRc;
		}

		return COMM_NO_ERROR;
	}

	return COMM_CANNOT_OPEN;
}

int Comm::close(void)
{
	if(_hCom != NULL)
	{
		::CloseHandle(_hCom);
		_hCom = NULL;
	}

	return COMM_NO_ERROR;
}

int Comm::setTimeOut(int iTimeOut)
{
	_COMMTIMEOUTS	ct;

	if(_hCom == NULL)
	{
		return COMM_NOT_OPENED;
	}

	if ( !::GetCommTimeouts(_hCom, &ct) )
	{
		return COMM_INVALID_COMMAND;
	}

	ct.ReadIntervalTimeout = 0;
	ct.ReadTotalTimeoutMultiplier = 0;
	ct.ReadTotalTimeoutConstant = iTimeOut;
	ct.WriteTotalTimeoutMultiplier = 0;
	ct.WriteTotalTimeoutConstant = iTimeOut;

	if ( !::SetCommTimeouts(_hCom, &ct) )
	{
		return COMM_INVALID_COMMAND;
	}

	return COMM_NO_ERROR;
}

int Comm::changeParameters(int iBaud, int iBit, int iParity, int iStopBit)
{
	DCB dcb;

	if(_hCom == NULL)
	{
		return COMM_NOT_OPENED;
	}
	
	if(iBaud<BAUD_075 || iBit<DATABITS_5 || iStopBit<STOPBITS_10)
	{
		return COMM_BAD_PARAMS;
	}

	if ( !::GetCommState(_hCom, &dcb))
	{
		return COMM_INVALID_COMMAND;
	}

	dcb.BaudRate = iBaud;
	dcb.ByteSize = iBit;
	dcb.Parity = iParity;
	dcb.StopBits = iStopBit;

	if (!::SetCommState(_hCom, &dcb))
	{
		return COMM_INVALID_COMMAND;
	}

	return COMM_NO_ERROR;
}

int Comm::sendData(const void *pData, size_t iLen, size_t *iSendedLen)
{
	DWORD result=0;

	if(_hCom == NULL)
	{
		return COMM_NOT_OPENED;
	}

	if( iLen<0 || pData==NULL)
	{
		return COMM_BAD_PARAMS;
	}

	if ( !::WriteFile(_hCom, pData, (DWORD)iLen, &result, 0) )
	{
		return COMM_INVALID_COMMAND;
	}
	else
	{
		if(iSendedLen != NULL)
			*iSendedLen = (size_t)result;
	}

	return COMM_NO_ERROR;
}

int Comm::receiveData(void *pData, size_t iMaxLen, size_t *iReceivedLen)
{
	DWORD result=0;

	if(_hCom == NULL)
	{
		return COMM_NOT_OPENED;
	}

	if( iMaxLen<0 || pData==NULL)
	{
		return COMM_BAD_PARAMS;
	}

	if (!ReadFile(_hCom, pData, iMaxLen, &result, 0))
	{
		return COMM_INVALID_COMMAND;
	}
	else
	{
		if(iReceivedLen != NULL)
			*iReceivedLen = (size_t)result;
	}

	return COMM_NO_ERROR;
}




